﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System.ComponentModel;
using System.Windows.Markup;
using Sebarf.Diagnostics.Interfaces;

#endregion

namespace Utils {
	/// <summary>
	/// defines a process step, that calls its next step if processed
	/// </summary>
	[DefaultProperty("NextStep")]
	[ContentProperty("NextStep")]
	public class ProcessStep<TSource> : IProcessStep {
		#region Public Properties

		/// <summary>
		/// is called after Process
		/// </summary>
		public ProcessStep<TSource> NextStep { get; set; }

		#endregion

		#region Public Methods

		/// <summary>
		/// returns if the process step can process the given object
		/// </summary>
		/// <param name="toProcess"></param>
		/// <returns></returns>
		public virtual bool CanProcess(TSource toProcess) {
			return true;
		}

		/// <summary>
		/// process the process step with the given object
		/// </summary>
		/// <param name="toProcess"></param>
		/// <returns></returns>
		public virtual object Process(TSource toProcess) {
			Check.AssertException(CanProcess(toProcess), "cannot process the given object");
			TSource toReturn = OnProcess(toProcess);
			if (NextStep == null) {
				return toReturn;
			}
			else {
				return NextStep.Process(toReturn);
			}
		}

		#endregion

		#region Private Methods

		protected virtual TSource OnProcess(TSource toProcess) {
			return toProcess;
		}

		#endregion

		#region IProcessStep Members

		public bool CanProcessItem(object o) {
			if (o is TSource) {
				return CanProcess((TSource)o);
			}
			else {
				return false;
			}
		}

		public void ProcessItem(object o) {
			Process((TSource)o);
		}

		public virtual IProcessStep GetNextStep() {
			return NextStep;
		}

		#endregion
	}
}